package com.mycat.codegenerator;

import com.mycat.codegenerator.config.FMConfig;
import com.mycat.codegenerator.conversion.DataConversion;
import com.mycat.codegenerator.db.DBHandler;
import com.mycat.codegenerator.entity.EntityBean;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.*;
import java.util.*;

/**
 * 代码生成器执行程序
 */
public class ExecutiveProgram {

    public static void main(String[] args) {
        try {
            Configuration config = new Configuration();
            config.setDirectoryForTemplateLoading(new File(FMConfig.tmpFilePath));

            List<String> tableNames = new ArrayList<String>() {{
                this.add("task_schedule_task");
                this.add("task_schedule_task_execute_detail");
            }};
            Map<String, List<EntityBean>> data = DataConversion.getData(DBHandler.getTables(tableNames));

            try {
                generatorXmlMapper(data,config);
                generatorEntity(data,config);
                generatorMapper(data,config);
                generatorService(data, config);
                generatorServiceImpl(data, config);
                generatorController(data, config);
                generatorJsp(data, config);
                generatorJs(data, config);
            } catch (TemplateException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void generatorJs(Map<String, List<EntityBean>> data, Configuration config) throws IOException, TemplateException {
        if (null == data || data.size() == 0) {
            return;
        }
        String savePath = FMConfig.savePath + "js/";
        Iterator<Map.Entry<String, List<EntityBean>>> javaScripts = data.entrySet().iterator();
        while (javaScripts.hasNext()) {
            Map.Entry<String, List<EntityBean>> javaScript = javaScripts.next();
            // 获取模板
            Template javaScriptTemplate = config.getTemplate("javaScript.ftl");
            // 获取生成后的文件
            File file = new File(savePath + javaScript.getKey() + ".js");
            if (file.exists()) {
                System.out.println(javaScript.getKey() + "  文件已经存在！");
                continue;
            }
            // 验证是否存在js文件夹，不存在则创建js文件夹
            File jsDir = new File(savePath);
            if (!jsDir.exists()) {
                jsDir.mkdirs();
            }
            // 设置数据
            Map<String, Object> entityData = new HashMap<>();
            entityData.put("beans", javaScript.getValue());
            entityData.put("moduleName", FMConfig.moduleName);
            entityData.put("entity_name", javaScript.getKey());
            entityData.put("entity_name_low", javaScript.getKey().substring(0, 1).toLowerCase() + javaScript.getKey().substring(1, javaScript.getKey().length()));
            // 根据模板生成文件
            Writer out = new OutputStreamWriter(new FileOutputStream(savePath + javaScript.getKey() + ".js"), "UTF-8");
            javaScriptTemplate.process(entityData, out);
        }
        System.out.println("生成js文件搞定。");
    }

    public static void generatorJsp(Map<String, List<EntityBean>> data, Configuration config) throws IOException, TemplateException {
        if (null == data || data.size() == 0) {
            return;
        }
        String savePath = FMConfig.savePath + "jsp/";
        Iterator<Map.Entry<String, List<EntityBean>>> jsps = data.entrySet().iterator();
        while (jsps.hasNext()) {
            Map.Entry<String, List<EntityBean>> jsp = jsps.next();
            // 获取模板
            Template jspTemplate = config.getTemplate("jsp.ftl");
            // 获取生成后的文件
            File file = new File(savePath + jsp.getKey() + ".jsp");
            if (file.exists()) {
                System.out.println(jsp.getKey() + "  文件已经存在！");
                continue;
            }
            // 验证是否存在jsp文件夹，不存在则创建jsp文件夹
            File jspDir = new File(savePath);
            if (!jspDir.exists()) {
                jspDir.mkdirs();
            }
            // 设置数据
            Map<String, Object> entityData = new HashMap<>();
            entityData.put("beans", jsp.getValue());
            entityData.put("elements",getElement(jsp.getValue()));
            entityData.put("moduleName", FMConfig.moduleName);
            entityData.put("entity_name", jsp.getKey());
            entityData.put("entity_name_low", jsp.getKey().substring(0, 1).toLowerCase() + jsp.getKey().substring(1, jsp.getKey().length()));
            // 根据模板生成文件
            Writer out = new OutputStreamWriter(new FileOutputStream(savePath + jsp.getKey() + ".jsp"), "UTF-8");
            jspTemplate.process(entityData, out);
        }
        System.out.println("生成jsp文件搞定。");
    }

    /**
     * 将所有字段信息转换为页面所需的元素
     * @param beans  List<EntityBean>
     * @return List<List<EntityBean>>
     */
    public static List<List<EntityBean>> getElement(List<EntityBean> beans) {
        List<List<EntityBean>> datas = new ArrayList<>();
        if (null == beans && beans.size() == 0) {
            return datas;
        }
        int i = 1;
        List<EntityBean> data = new ArrayList<>();
        for (EntityBean bean : beans) {
            // 跳过设置创建时间和修改时间
            if(bean.getPropertyName().equalsIgnoreCase("createDate")
                    || bean.getPropertyName().equalsIgnoreCase("updateDate")){
                continue;
            }
            if (i % 2 != 0 && i != 1) {
                data = new ArrayList<>();
            }
            data.add(bean);
            if (i % 2 == 0) {
                datas.add(data);
            }
            i++;
        }
        if (i % 2 == 0) {
            datas.add(data);
        }
        return datas;
    }

    public static void generatorController(Map<String, List<EntityBean>> data, Configuration config) throws IOException, TemplateException {
        if (null == data || data.size() == 0) {
            return;
        }
        String savePath = FMConfig.savePath + "controller/";
        Iterator<Map.Entry<String, List<EntityBean>>> controllers = data.entrySet().iterator();
        while (controllers.hasNext()) {
            Map.Entry<String, List<EntityBean>> controller = controllers.next();
            // 获取模板
            Template controllerTemplate = config.getTemplate("Controller.ftl");
            // 获取生成后的文件
            File file = new File(savePath + controller.getKey() + "Controller.java");
            if (file.exists()) {
                System.out.println(controller.getKey() + "  文件已经存在！");
                continue;
            }
            // 验证是否存在controller文件夹，不存在则创建controller文件夹
            File controllerDir = new File(savePath);
            if (!controllerDir.exists()) {
                controllerDir.mkdirs();
            }
            // 设置数据
            Map<String, Object> entityData = new HashMap<>();
            entityData.put("packageName", FMConfig.packageName);
            entityData.put("moduleName", FMConfig.moduleName);
            entityData.put("entity_name", controller.getKey());
            entityData.put("entity_name_low", controller.getKey().substring(0, 1).toLowerCase() + controller.getKey().substring(1, controller.getKey().length()));
            // 根据模板生成文件
            Writer out = new OutputStreamWriter(new FileOutputStream(savePath + controller.getKey() + "Controller.java"), "UTF-8");
            controllerTemplate.process(entityData, out);
        }
        System.out.println("生成controller文件搞定。");
    }


    public static void generatorServiceImpl(Map<String, List<EntityBean>> data, Configuration config) throws IOException, TemplateException {
        if (null == data || data.size() == 0) {
            return;
        }
        String savePath = FMConfig.savePath + "impl/";
        Iterator<Map.Entry<String, List<EntityBean>>> services = data.entrySet().iterator();
        while (services.hasNext()) {
            Map.Entry<String, List<EntityBean>> serviceImpl = services.next();
            // 获取模板
            Template serviceTemplate = config.getTemplate("serviceImpl.ftl");
            // 获取生成后的文件
            File file = new File(savePath + serviceImpl.getKey() + "ServiceImpl.java");
            if (file.exists()) {
                System.out.println(serviceImpl.getKey() + "  文件已经存在！");
                continue;
            }
            // 验证是否存在impl文件夹，不存在则创建impl文件夹
            File serviceDir = new File(savePath);
            if (!serviceDir.exists()) {
                serviceDir.mkdirs();
            }
            // 设置数据
            Map<String, Object> entityData = new HashMap<>();
            entityData.put("packageName", FMConfig.packageName);
            entityData.put("moduleName", FMConfig.moduleName);
            entityData.put("entity_name", serviceImpl.getKey());
            entityData.put("entity_name_low", serviceImpl.getKey().substring(0, 1).toLowerCase() + serviceImpl.getKey().substring(1, serviceImpl.getKey().length()));
            // 根据模板生成文件
            Writer out = new OutputStreamWriter(new FileOutputStream(savePath + serviceImpl.getKey() + "ServiceImpl.java"), "UTF-8");
            serviceTemplate.process(entityData, out);
        }
        System.out.println("生成ServiceImpl文件搞定。");
    }

    public static void generatorService(Map<String, List<EntityBean>> data, Configuration config) throws IOException, TemplateException {
        if (null == data || data.size() == 0) {
            return;
        }
        String savePath = FMConfig.savePath + "service/";
        Iterator<Map.Entry<String, List<EntityBean>>> services = data.entrySet().iterator();
        while (services.hasNext()) {
            Map.Entry<String, List<EntityBean>> service = services.next();
            // 获取模板
            Template serviceTemplate = config.getTemplate("service.ftl");
            // 获取生成后的文件
            File file = new File(savePath + service.getKey() + "Service.java");
            if (file.exists()) {
                System.out.println(service.getKey() + "  文件已经存在！");
                continue;
            }
            // 验证是否存在service文件夹，不存在则创建service文件夹
            File serviceDir = new File(savePath);
            if (!serviceDir.exists()) {
                serviceDir.mkdirs();
            }
            // 设置数据
            Map<String, Object> entityData = new HashMap<>();
            entityData.put("packageName", FMConfig.packageName);
            entityData.put("moduleName", FMConfig.moduleName);
            entityData.put("entity_name", service.getKey());
            entityData.put("entity_name_low", service.getKey().substring(0, 1).toLowerCase() + service.getKey().substring(1, service.getKey().length()));
            // 根据模板生成文件
            Writer out = new OutputStreamWriter(new FileOutputStream(savePath + service.getKey() + "Service.java"), "UTF-8");
            serviceTemplate.process(entityData, out);
        }
        System.out.println("生成Service文件搞定。");
    }

    public static void generatorMapper(Map<String, List<EntityBean>> data, Configuration config) throws IOException, TemplateException {
        if (null == data || data.size() == 0) {
            return;
        }
        String savePath = FMConfig.savePath + "mapper/";
        Iterator<Map.Entry<String, List<EntityBean>>> entitys = data.entrySet().iterator();
        while (entitys.hasNext()) {
            Map.Entry<String, List<EntityBean>> entity = entitys.next();
            // 获取模板
            Template xmlTemplate = config.getTemplate("Mapper.ftl");
            // 获取生成后的文件
            File file = new File(savePath + entity.getKey() + "Mapper.java");
            if (file.exists()) {
                System.out.println(entity.getKey() + "  文件已经存在！");
                continue;
            }
            // 验证是否存在mapper文件夹，不存在则创建mapper文件夹
            File mapperDir = new File(savePath);
            if (!mapperDir.exists()) {
                mapperDir.mkdirs();
            }
            // 设置数据
            Map<String, Object> entityData = new HashMap<>();
            entityData.put("packageName", FMConfig.packageName);
            entityData.put("moduleName", FMConfig.moduleName);
            entityData.put("entity_name", entity.getKey());
            // 根据模板生成文件
            Writer out = new OutputStreamWriter(new FileOutputStream(savePath + entity.getKey() + "Mapper.java"), "UTF-8");
            xmlTemplate.process(entityData, out);
        }
        System.out.println("生成Mapper文件搞定。");
    }

    /**
     * 生成entity
     *
     * @param data   转换后的数据
     * @param config Configuration
     */
    public static void generatorEntity(Map<String, List<EntityBean>> data, Configuration config) throws IOException, TemplateException {
        if (null == data || data.size() == 0) {
            return;
        }
        String savePath = FMConfig.savePath + "entity/";
        Iterator<Map.Entry<String, List<EntityBean>>> entitys = data.entrySet().iterator();
        while (entitys.hasNext()) {
            Map.Entry<String, List<EntityBean>> entity = entitys.next();
            // 获取模板
            Template xmlTemplate = config.getTemplate("Entity.ftl");
            // 获取生成后的文件
            File file = new File(savePath + entity.getKey() + ".java");
            if (file.exists()) {
                System.out.println(entity.getKey() + "  文件已经存在！");
                continue;
            }
            // 验证是否存在entity文件夹，不存在则创建entity文件夹
            File entityDir = new File(savePath);
            if (!entityDir.exists()) {
                entityDir.mkdirs();
            }
            // 设置数据
            Map<String, Object> entityData = new HashMap<>();
            entityData.put("packageName", FMConfig.packageName);
            entityData.put("moduleName", FMConfig.moduleName);
            entityData.put("entity_name", entity.getKey());
            entityData.put("tableName", entity.getValue().get(0).getTableName());
            entityData.put("beans", entity.getValue());
            // 根据模板生成文件
            Writer out = new OutputStreamWriter(new FileOutputStream(savePath + entity.getKey() + ".java"), "UTF-8");
            xmlTemplate.process(entityData, out);
        }
        System.out.println("生成Entity文件搞定。");
    }

    /**
     * 生成mybatis的xml文件
     *
     * @param data   转换后的数据
     * @param config Configuration
     */
    public static void generatorXmlMapper(Map<String, List<EntityBean>> data, Configuration config) throws IOException, TemplateException {
        if (null == data || data.size() == 0) {
            return;
        }
        String savePath = FMConfig.savePath + "xml/";
        Iterator<Map.Entry<String, List<EntityBean>>> entitys = data.entrySet().iterator();
        while (entitys.hasNext()) {
            Map.Entry<String, List<EntityBean>> entity = entitys.next();
            // 获取模板
            Template xmlTemplate = config.getTemplate("XmlMapper.ftl");
            // 获取生成后的文件
            File file = new File(savePath + entity.getKey() + "Mapper.xml");
            if (file.exists()) {
                System.out.println(entity.getKey() + "  文件已经存在！");
                continue;
            }
            // 验证是否存在xml文件夹，不存在则创建xml文件夹
            File xmlDir = new File(savePath);
            if (!xmlDir.exists()) {
                xmlDir.mkdirs();
            }
            // 设置数据
            Map<String, Object> xmlData = new HashMap<>();
            xmlData.put("packageName", FMConfig.packageName);
            xmlData.put("moduleName", FMConfig.moduleName);
            xmlData.put("entity_name", entity.getKey());
            xmlData.put("entity_name_low", entity.getKey().substring(0, 1).toLowerCase() + entity.getKey().substring(1, entity.getKey().length()));
            xmlData.put("beans", entity.getValue());
            // 根据模板生成文件
            Writer out = new OutputStreamWriter(new FileOutputStream(savePath + entity.getKey() + "Mapper.xml"), "UTF-8");
            xmlTemplate.process(xmlData, out);
        }
        System.out.println("生成Mapper.xml文件搞定。");
    }

}
